/**
 * There are code generation
 */
package com.neusoft.lohas.modules.ivm.entity.order;

import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.annotations.Where;

import com.google.common.collect.Lists;
import com.neusoft.lohas.common.persistence.IdEntity;
import com.neusoft.lohas.common.utils.DateUtils;
import com.neusoft.lohas.modules.ivm.entity.merchant.DeliveryIndent;
import com.neusoft.lohas.modules.ivm.entity.merchant.Merchant;
import com.neusoft.lohas.modules.ivm.entity.merchant.TimeSlot;
import com.neusoft.lohas.modules.ivm.entity.workflow.WorkFlow;
import com.neusoft.lohas.modules.ivm.enums.order.OrderTypeEnum;
import com.neusoft.lohas.modules.ivm.enums.order.PayStatusEnum;
import com.neusoft.lohas.modules.ivm.enums.order.PayTypeEnum;
import com.neusoft.lohas.modules.sys.entity.User;

/**
 * 商品订单Entity
 * 
 * @author Jackie.Liu
 * @version 2014-12-16
 */
@Entity
@Table(name = "ivm_order")
@DynamicInsert
@DynamicUpdate
public class Order extends IdEntity<Order> {

	private static final long serialVersionUID = 1L;
	private Merchant merchant; // 所属商户
	private String orderNo; // 订单号（提交订单时生成）
	private String tradeNo; // 交易号（支付后返回的账单号）
	private int totalNumber; //订单商品总数量
	private double amount; // 订单总金额
	private OrderDiscount orderDiscount; // 折扣编号，对应订单折扣表主键Id
	private double disAmount; // 折扣后总金额
	// 支付状态：(0:未付款, 1:已付款)
	private String payStatus; 
	// 支付类型：1货到付款，2支付宝，3银联，4微信
	private String payType; 
	// 订单处理状态：(0:等待派送, 1:正在派送, 2:已派送)
	private String orderType; 
	private Date payDate; // 支付成功的时间，与订单生成时间区分开
	private User user; // 订单所属用户
	private UserAddress userAddress; // 用户地址ID（收货地址）
	private Date deliveryDate; //配送日期，格式：yyyy-MM-dd
	private TimeSlot timeSlot; // 用户选择的收货时间ID
	private DeliveryIndent deliveryIndent; //送达时间ID
	private WorkFlow workFlow;   //流程
	private DeliveryInfo deliveryInfo;   //送货信息
	private int workflowNode; //订单流程节点值
	//订单确认状态0未确认，1已确认
	private String confirm;
	private String prompt; //温馨提示
	private String timeText; //收货时间
	private String finish; //结款状态：0未结款，1结款，2退回（金额不符）

	private List<OrderDetail> detailList = Lists.newArrayList(); // 订单详情列表
	private List<OrderDetailItem> detailItemList = Lists.newArrayList(); // 订单详情列表(订单商品列表备份)
	private List<DeliveryDetail> deliveryList = Lists.newArrayList(); //送货单列表
	
	public Order() {
		super();
	}

	public Order(String id) {
		this();
		this.id = id;
	}

	@ManyToOne
	@JoinColumn(name="merchant_id")
	@NotFound(action = NotFoundAction.IGNORE)
	@NotNull(message="归属商户不能为空")
	public Merchant getMerchant() {
		return merchant;
	}

	public void setMerchant(Merchant merchant) {
		this.merchant = merchant;
	}

	public String getOrderNo() {
		return orderNo;
	}

	public void setOrderNo(String orderNo) {
		this.orderNo = orderNo;
	}

	@Transient
	public String getDeliveryNo() {
		return "D"+this.orderNo.substring(2);
	}

	public String getTradeNo() {
		return tradeNo;
	}

	public void setTradeNo(String tradeNo) {
		this.tradeNo = tradeNo;
	}

	public int getTotalNumber() {
		return totalNumber;
	}

	public void setTotalNumber(int totalNumber) {
		this.totalNumber = totalNumber;
	}

	public double getAmount() {
		return amount;
	}

	public void setAmount(double amount) {
		this.amount = amount;
	}

	@ManyToOne
	@JoinColumn(name="discount_id")
	@NotFound(action = NotFoundAction.IGNORE)
	public OrderDiscount getOrderDiscount() {
		return orderDiscount;
	}

	public void setOrderDiscount(OrderDiscount orderDiscount) {
		this.orderDiscount = orderDiscount;
	}

	public double getDisAmount() {
		return disAmount;
	}

	public void setDisAmount(double disAmount) {
		this.disAmount = disAmount;
	}

	public String getPayStatus() {
		return payStatus;
	}

	public void setPayStatus(String payStatus) {
		this.payStatus = payStatus;
	}

	public String getPayType() {
		return payType;
	}

	public void setPayType(String payType) {
		this.payType = payType;
	}

	public String getOrderType() {
		return orderType;
	}

	public void setOrderType(String orderType) {
		this.orderType = orderType;
	}

	public Date getPayDate() {
		return payDate;
	}

	public void setPayDate(Date payDate) {
		this.payDate = payDate;
	}

	@ManyToOne
	@JoinColumn(name="user_id")
	@NotFound(action = NotFoundAction.IGNORE)
	@NotNull(message="所属用户不能为空")
	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	@ManyToOne
	@JoinColumn(name="address_id")
	@NotFound(action = NotFoundAction.IGNORE)
	@NotNull(message="用户收货地址不能为空")
	public UserAddress getUserAddress() {
		return userAddress;
	}

	public void setUserAddress(UserAddress userAddress) {
		this.userAddress = userAddress;
	}

	public Date getDeliveryDate() {
		return deliveryDate;
	}

	public void setDeliveryDate(Date deliveryDate) {
		this.deliveryDate = deliveryDate;
	}

	@ManyToOne
	@JoinColumn(name="slot_id")
	@NotFound(action = NotFoundAction.IGNORE)
	public TimeSlot getTimeSlot() {
		return timeSlot;
	}

	public void setTimeSlot(TimeSlot timeSlot) {
		this.timeSlot = timeSlot;
	}

	@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "order")
	@Where(clause="del_flag='"+DEL_FLAG_NORMAL+"'")
	@NotFound(action = NotFoundAction.IGNORE)
	public List<OrderDetail> getDetailList() {
		return detailList;
	}

	public void setDetailList(List<OrderDetail> detailList) {
		this.detailList = detailList;
	}
	
	@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "order")
	@Where(clause="del_flag='"+DEL_FLAG_NORMAL+"'")
	@NotFound(action = NotFoundAction.IGNORE)
	public List<OrderDetailItem> getDetailItemList() {
		return detailItemList;
	}

	public void setDetailItemList(List<OrderDetailItem> detailItemList) {
		this.detailItemList = detailItemList;
	}
	
	@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "order")
	@Where(clause="del_flag='"+DEL_FLAG_NORMAL+"'")
	@OrderBy("sort")
	@NotFound(action = NotFoundAction.IGNORE)
	public List<DeliveryDetail> getDeliveryList() {
		return deliveryList;
	}

	public void setDeliveryList(List<DeliveryDetail> deliveryList) {
		this.deliveryList = deliveryList;
	}

	@OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER, mappedBy = "order")
	@NotFound(action = NotFoundAction.IGNORE)
	public DeliveryIndent getDeliveryIndent() {
		return deliveryIndent;
	}

	public void setDeliveryIndent(DeliveryIndent deliveryIndent) {
		this.deliveryIndent = deliveryIndent;
	}
	
	@OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "order")
	@Where(clause="del_flag='"+DEL_FLAG_NORMAL+"'")
	@NotFound(action = NotFoundAction.IGNORE)
	public WorkFlow getWorkFlow() {
		return workFlow;
	}

	public void setWorkFlow(WorkFlow workFlow) {
		this.workFlow = workFlow;
	}
	
	@OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "order")
	@Where(clause="del_flag='"+DEL_FLAG_NORMAL+"'")
	@NotFound(action = NotFoundAction.IGNORE)
	public DeliveryInfo getDeliveryInfo() {
		return deliveryInfo;
	}

	public void setDeliveryInfo(DeliveryInfo deliveryInfo) {
		this.deliveryInfo = deliveryInfo;
	}

	@Transient
	public String getPayStatusDesc() {
		return PayStatusEnum.getEnumPayStatusDescByStatus(Integer.valueOf(payStatus));
	}

	@Transient
	public String getPayTypeDesc() {
		return PayTypeEnum.getEnumPayTypeDescByStatus(Integer.valueOf(payType));
	}

	@Transient
	public String getOrderTypeDesc() {
		return OrderTypeEnum.getEnumOrderTypeDescByStatus(Integer.valueOf(orderType));
	}
	
	@Transient
	public boolean isCanDelivery(){
		boolean result = true;
		for (OrderDetail orderDetail : detailList) {
			if (orderDetail.getProduct().getStock()<orderDetail.getNumber()) {
				result = false; break;
			}
		}
		return result;
	}
	
	@Transient
	public String getCanDeliveryText(){
		String result = "<br>商品如下：<br>";
		String text = "";
		for (OrderDetail orderDetail : detailList) {
			if (orderDetail.getProduct().getStock()<orderDetail.getNumber()) {
				text += "、"+orderDetail.getProduct().getName();
			}
		}
		if (StringUtils.isNotBlank(text)) {
			text = text.substring(1);
		}
		return result+text;
	}

	@Transient
	public int getWorkflowNode() {
		WorkFlow workflow = this.getWorkFlow();
		//待付款
		if (!this.getPayType().equals("1") && this.getPayStatus().equals("0")) {
			this.setWorkflowNode(1);
		}
		//已支付，处理中
		else if (!this.getPayType().equals("1") && this.getPayStatus().equals("1") && workflow == null && (this.getDeliveryIndent() == null || StringUtils.isBlank(this.getDeliveryIndent().getId()))) {
			this.setWorkflowNode(2);
		}
		//货到付款，处理中
		else if (this.getPayType().equals("1") && this.getPayStatus().equals("0") && workflow == null && (this.getDeliveryIndent() == null || StringUtils.isBlank(this.getDeliveryIndent().getId()))) {
			this.setWorkflowNode(3);
		}
		//已支付，处理中，已指定送货员
		else if (!this.getPayType().equals("1") && this.getPayStatus().equals("1") && this.getDeliveryIndent() != null && StringUtils.isNotBlank(this.getDeliveryIndent().getId()) && this.getDeliveryIndent().getDeliveryMember() != null && StringUtils.isNotBlank(this.getDeliveryIndent().getDeliveryMember().getId()) && this.getOrderType().equals("0")) {
			this.setWorkflowNode(4);
		}
		//已支付，处理中，已指定送货员，配送中
		else if (!this.getPayType().equals("1") && this.getPayStatus().equals("1") && workflow != null && workflow.getStatus().equals("1") && this.getOrderType().equals("1")) {
			this.setWorkflowNode(5);
		}
		//已支付，处理中，已指定送货员，配送中，已完成
		else if (!this.getPayType().equals("1") && this.getPayStatus().equals("1") && workflow != null && workflow.getStatus().equals("1") && this.getOrderType().equals("2")) {
			this.setWorkflowNode(6);
		}
		//货到付款，处理中，已指定送货员
		else if (this.getPayType().equals("1") && this.getPayStatus().equals("0") && this.getDeliveryIndent() != null && StringUtils.isNotBlank(this.getDeliveryIndent().getId()) && this.getDeliveryIndent().getDeliveryMember() != null && StringUtils.isNotBlank(this.getDeliveryIndent().getDeliveryMember().getId()) && this.getOrderType().equals("0")) {
			this.setWorkflowNode(7);
		}
		//货到付款，处理中，已指定送货员，配送中
		else if (this.getPayType().equals("1") && this.getPayStatus().equals("0") && workflow != null && workflow.getStatus().equals("1") && this.getOrderType().equals("1")) {
			this.setWorkflowNode(8);
		}
		//货到付款，处理中，已指定送货员，配送中，已完成
		else if (this.getPayType().equals("1") && this.getPayStatus().equals("1") && workflow != null && workflow.getStatus().equals("1") && this.getOrderType().equals("2")) {
			this.setWorkflowNode(9);
		}//如果直接完成，处理之前操作的订单
		else if (this.getOrderType().equals("2")) {
			this.setWorkflowNode(9);
		}
		return workflowNode;
	}

	public void setWorkflowNode(int workflowNode) {
		this.workflowNode = workflowNode;
	}
	
	@Transient
	public String getCreateDateStr(){
		if(this.getCreateDate()==null) return "1900-01-01 00:00:00";
		return DateUtils.formatDate(this.getCreateDate(), DateUtils.parsePatterns[1]);
	}

	public String getConfirm() {
		return confirm;
	}

	public void setConfirm(String confirm) {
		this.confirm = confirm;
	}
	
	public String getFinish() {
		return finish;
	}

	public void setFinish(String finish) {
		this.finish = finish;
	}

	//以下是收货人信息，导出派送单需要
	//收货人姓名
	@Transient
	public String getName(){
		String name = "";
		if(this.deliveryInfo==null){
			name = this.userAddress.getName();
		}else{
			name = this.deliveryInfo.getName();
		}
		return name;
	}
	//收货人地址
	@Transient
	public String getAddress(){
		String address = "";
		if(this.deliveryInfo==null){
			address = this.userAddress.getDetailAddress();
		}else{
			address = this.deliveryInfo.getAddress();
		}
		return address;
	}
	//收货人电话
	@Transient
	public String getPhone(){
		String phone = "";
		if(this.deliveryInfo==null){
			phone = this.userAddress.getPhone();
		}else{
			phone = this.deliveryInfo.getPhone();
		}
		return phone;
	}
	//下单时的收货时间
	public String getTimeText(){
		return timeText;
	}
	
	public void setTimeText(String timeText) {
		this.timeText = timeText;
	}

	//温馨提示
	@Transient
	public String getPrompt(){
		return prompt;
	}

	public void setPrompt(String prompt) {
		this.prompt = prompt;
	}
	//应退金额
	@Transient
	public double getRefund() {
		double refund = 0.0;
		if(this.deliveryInfo!=null){
			refund = this.deliveryInfo.getRefund();
		}
		return refund;
	}
	//实退，实收金额
	@Transient
	public double getRealRefund() {
		double real = 0.0;
		if(payType.equals("1")){//到付
			if(this.deliveryInfo!=null){
				real = this.deliveryInfo.getRealAmount();
			}
		}else{
			if(this.deliveryInfo!=null){
				real = this.deliveryInfo.getRealRefund();
			}
		}
		return real;
	}
	//送货单总金额
	@Transient
	public double getDeliveryAmount() {
		if(this.deliveryInfo==null){
			return amount;
		}else{
			return this.deliveryInfo.getAmount();
		}
	}
	//送货时选的时间
	@Transient
	public String getOrderTimeText(){
		if(this.deliveryInfo==null){
			return timeText;
		}else{
			return this.deliveryInfo.getTimeText();
		}
	}
	
}
